package space.misiro.ledgers.keycloak.client.mapper

import KeycloakClient
import org.keycloak.representations.idm.*
import org.mapstruct.Mapper
import space.misiro.ledgers.keycloak.client.model.KeycloakRealm
import space.misiro.ledgers.keycloak.client.model.KeycloakUser

@Mapper(componentModel = "spring")
interface KeycloakDataMapper {

    /**
     * 将自定义领域模型转换为Keycloak的领域表示对象
     * @param realm 自定义领域模型对象，包含领域配置信息
     * @return 符合Keycloak API要求的领域表示对象
     */
    fun createRealmRepresentation(realm: KeycloakRealm): RealmRepresentation

    /**
     * 创建Keycloak客户端作用域表示对象
     * @param name 客户端作用域名称
     * @return 预配置的客户端作用域对象，包含：
     *         - openid-connect协议
     *         - 同意屏幕显示标记
     *         - 包含在token作用域标记
     */
    fun createClientScopeRepresentation(name: String) = ClientScopeRepresentation().apply {
        this.name = name
        protocol = "openid-connect"
        attributes =
            mapOf<String, String>("display.on.consent.screen" to "true", "include.in.token.scope" to "true")
    }

    /**
     * 创建Keycloak角色表示对象
     * @param realmRole 角色名称
     * @return 基础角色配置对象，包含：
     *         - 非复合角色标记
     *         - 指定角色名称
     */
    fun createRoleRepresentation(realmRole: String) = RoleRepresentation().apply {
        name = realmRole
        isComposite = false
    }

    /**
     * 将自定义客户端模型转换为Keycloak客户端表示对象
     * @param client 自定义客户端配置模型，包含：
     *        - 客户端ID
     *        - 密钥（可选）
     *        - 公共客户端标记
     *        - 允许的Web来源
     *        - 重定向URI列表
     * @return 完整配置的客户端表示对象，包含：
     *         - 授权服务启用标记
     *         - 服务账号启用标记
     *         - 权限范围配置
     */
    fun createClientRepresentation(client: KeycloakClient) = ClientRepresentation().apply {
        clientId = client.clientId
        name = client.clientId
        isDirectAccessGrantsEnabled = true
        secret = client.clientSecret.takeUnless { client.publicClient }
        webOrigins = client.webOrigins
        isPublicClient = client.publicClient
        isFullScopeAllowed = client.fullScopeAllowed
        authorizationServicesEnabled = true
        isServiceAccountsEnabled = true
        redirectUris = client.redirectUrls
    }

    /**
     * 将自定义用户模型转换为Keycloak用户表示对象
     * @param user 自定义用户模型，包含：
     *        - 登录凭证
     *        - 个人基本信息
     *        - 账户状态
     *        - 领域角色
     * @return 完整用户配置对象，包含：
     *         - 密码凭证配置（临时标记设为false）
     *         - 邮箱验证状态
     *         - 空客户端角色初始化
     */
    fun createUserRepresentation(user: KeycloakUser) = UserRepresentation().apply {
        username = user.login
        firstName = user.firstName
        lastName = user.lastName
        email = user.email
        isEnabled = user.enabled
        clientRoles = emptyMap()
        realmRoles = user.realmRoles
        isEmailVerified = user.emailVerified
        credentials = emptyList()
        credentials.add(CredentialRepresentation().apply {
            type = CredentialRepresentation.PASSWORD
            value = user.password
            isTemporary = false
        })
    }

    /**
     * 生成用户更新表示对象，保留原始用户表示的基础信息
     * @param userRepresentation 原始用户表示对象
     * @param user 包含更新数据的用户模型
     * @return 合并后的更新对象，包含：
     *         - 更新的用户基本信息
     *         - 领域角色配置
     *         - 不包含凭证和客户端角色信息
     */
    fun toUpdateUserPresentation(userRepresentation: UserRepresentation, user: KeycloakUser) =
        UserRepresentation().apply {
            username = user.login
            firstName = user.firstName
            lastName = user.lastName
            isEnabled = user.enabled
            isEmailVerified = user.emailVerified
            email = user.email
            realmRoles = user.realmRoles
        }
}